MaxTypeLen = 100
HashSize = 4
MaxPar = 10
MaxFunctionLength  = 500
'''
 We have intoduced three variables to take care of all type of declaration : type_qualifier(qualifier) , type_specifier(specifier) , 
    storage_class_specifier(storage)
    
    qualifier 
	1 ------ CONST
	2 ------ VOLATILE
	
	 storage
	1 ------ TYPEDEF
	2 ------ EXTERN
	3 ------ STATIC
	4 ------ AUTO
	5 ------ REGISTER
	
    specifier 
	1 ------ VOID
	2 ------ CHAR
	3 ------ SHORT
	4 ------ INT
	5 ------ LONG
	6 ------ FLOAT
	7 ------ DOUBLE
	8 ------ SIGNED
	9 ------ UNSIGNED
	 ------ struct_or_union_specifier
	10 ----- enum_specifier
	11 ----- TYPE_NAME
	12------Struct
	13------Union
	
    type = qualifier + storage*10 + specifier*100 +// isFunction*1000 + isPointer*10000


/* Abhi ke liye sirf single level pointer, upar likhe specifier aur function without overloading implement kar rahe hain... */
'''
#typeSpecifier 

Int = 0
Char = 1
Float = 2
Double = 3
Long = 4
Void = 5


class SymEntry:
      global MaxPar
      def __init__(self):
	    self.id = ""
	    self.scope = 0
	    self.type = 0
	    self.keywordval = 0 #//UNION, INT , etc.
	    self.linenum = 0
	    self.isPointer = 0
	    self.isArray = 0
	    self.ArrayLimit = 0
	    self.isFunction = 0
	    self.offset = 0
	    self.width = 0
	    self.numParameters = 0
	    self.ParameterList = []
	    for i in range(MaxPar):
		  temp = Attribute()
		  self.ParameterList.append(temp) 
	    #Will hold parameter List if the isFunction flag=1;	    
	    self.next = None

class Attribute:
      global MaxPar
      def __init__(self):
	    #self.type = ""
	    self.id = ""
	    self.type = 0
	    self.isArray = 0 	#// True if variable is array
	    self.ArrayLimit = 0 # upper limit of array (valid if DIMENSION is true)
	    self.width = 0
	    self.isPointer = 0
	    self.qualifier = 0
	    self.specifier = 0
	    self.storage = 0
	    self.scope = 0	#//ISKI ZARURAT HI KYA HAI AS IN ATTRIBUTES!!!!
	    self.IntConstValue = 0	# because this g++ compiler set 4 byte for long but we are setting 8 bytes
	    self.IntConst = 0
	    self.FloatConstValue = 0.0	# to store the value of double or float      
	    self.StringValue = ""
	    self.isFunction = 0
	    self.numParameters = 0
	    self.isString = 0
	    self.offset = 0
	    self.code = ""
	    self.icode = ""
	    self.ParameterList = []
	    for i in range(MaxPar):
		  temp = None
		  self.ParameterList.append(temp)
	    #Will hold parameter List if the isFunction flag=1;	

class VALUE:
      def __init__(self):
	    self.intValue = 0
	    self.longIntValue = 0
	    self.floatValue = 0.0
	    self.doubleValue = 0.0
	    self.charValue = ""
	    self.string = ""

'''
struct ScopeEntry{	//---used in original

	char *id; 	//Identifier name
	union VALUE v;	//Its value
	char *scope;	//Its scope
	char *labelScope;	//If idName is a lebel, scope contains "label". So this is the scope to which the label belongs.
	char *type;	//Its type
	int width;
	struct ScopeEntry *next;	//pointer to next node
	int Const;			// store whether identifier is const or not
	int ptrConst;		// store const pointer 
	int doubleptr;			//nkbansal
	int doubleptrConst;			//nkbansal
	int IntConst;		//enumerated identifiers are Integer constant can be used any where just like literal constants
	int stackOffset;//	   
	int heapOffset;//    
	//int width;	//   
	int ptr;
	int functionFlag;
	int functionOverloading;//free slot index of overloaded functions put at same node in scopeTable
	struct ScopeEntry *parameterList[10];//parameter list
	int definitionFlag[10];//has the function been declared
	char * returntype[10];
	int functionDeclareFlag;
	int activationRecordSize;
};
'''

class SymTableNode:
      global HashSize
      def __init__(self):
	    self.scope = 0
	    self.name = ""
	    self.table = []
	    for i in range(HashSize):
		  temp = SymEntry()
		  self.table.append(temp) 
	    self.next = None 

'''
struct ScopeTableNode {		//---used in original
  char *scope;  
  struct ScopeEntry *table[HashSize];
  struct ScopeTableNode *next;
};
'''

# global name used in other places
global1 = []
for i in range(2):
      temp = SymTableNode()
      global1.append(temp) 

tail = []
for i in range(2):
      temp = SymTableNode()
      tail.append(temp) 
      
'''
struct ScopeTableNode *Global;		//---used in original
struct ScopeTableNode *Tail;  
'''


'''
struct SymTableNode *CreateNewSymTableNode();
struct SymEntry* lookup(char *,int);
struct SymEntry *InsertSymTable(char *,int,int,int);
void PopSym(int);

/*void InitializeScopeTable();				//----used in original
struct ScopeEntry *InsertScopeTable(char *name,char* currentScope,char* typ);
struct ScopeEntry* Scopelookup(char *name);
struct ScopeTableNode *CreateNewScopeTableNode();*/

struct Attribute * initAttr(struct Attribute*);
struct Attribute *PassAttribute(struct Attribute *a1);
struct Attribute *PassSymEntry(struct SymEntry *a1);
//struct Attribute *temp_inherted;
int CheckBeforeMerge(struct Attribute* a1,struct Attribute* a2);
struct Attribute * MergeAttributes3Code(struct Attribute* a1,struct Attribute* a2);
void PrintAttribute(struct Attribute *a);
void PrintSymEntry(struct SymEntry *a);
void PrintSymTable();
'''